﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ZhongJia.Lock.Infrastructure;
using ZhongJia.Lock.Web.Extensions;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.AspNetCore.Http;
using ZhongJia.Lock.Core.Services;

namespace ZhangJia.Lock.Web
{
    public class Startup
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly int? sslPort;
        public Startup(IHostingEnvironment env)
        {
            _hostingEnvironment = env;

            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();

            if (env.IsDevelopment())
            {
                var launchConfiguration = new ConfigurationBuilder()
                   .SetBasePath(env.ContentRootPath)
                   .AddJsonFile(@"Properties\launchSettings.json")
                   .Build();
                this.sslPort = launchConfiguration.GetValue<int>("iisSettings:iisExpress:sslPort");
            }
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            GlobalConfiguration.WebRootPath = _hostingEnvironment.WebRootPath;
            GlobalConfiguration.ContentRootPath = _hostingEnvironment.ContentRootPath;
            GlobalConfiguration.PortalHost = Configuration["SystemSettings:Host"];
            services.AddCaching()
                    .AddCustomOptions(Configuration)
                    .AddResponseCaching()
                    .AddCustomResponseCompression(Configuration)
                    .AddSwagger()
                    .AddCustomVersioning()
                    .AddMvcCore()
                    .AddApiExplorer()
                    .AddAuthorization()
                    .AddFormatterMappings()
                    .AddDataAnnotations()
                    .AddJsonFormatters()
                    .AddCustomJsonOptions()
                    .AddCustomCors()
                    .AddVersionedApiExplorer()
                    .AddCustomMvcOptions(Configuration, _hostingEnvironment);

            services.AddCustomizedDataStore(Configuration);
            services.AddCustomerIdentityServer(Configuration);
            services.AddCustomizedMvc();
            services.AddCustomizedService();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
        {
            if (env.IsDevelopment())
            {
                loggerfactory.AddConsole(Configuration.GetSection("Logging")).AddDebug();
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
            {
                Authority = GlobalConfiguration.PortalHost,
                RequireHttpsMetadata = false,
                ApiName = "api.lcok"
            });

            app.UseIdentityServer();
            app
                   //.UseRewriter(
                   //    new RewriteOptions().AddRedirectToHttps(StatusCodes.Status301MovedPermanently, this.sslPort))
                   .UseResponseCaching()
                   .UseResponseCompression()
                   .UseStaticFilesWithCacheControl(Configuration)
                   .UseCors("AllowAny")
                   .UseMvc()
                   .UseSwagger()
                   .UseSwaggerUI(
                       options =>
                       {
                           var provider = app.ApplicationServices.GetService<IApiVersionDescriptionProvider>();
                           foreach (var apiVersionDescription in provider
                               .ApiVersionDescriptions
                               .OrderByDescending(x => x.ApiVersion))
                           {
                               options.SwaggerEndpoint(
                                   $"/swagger/{apiVersionDescription.GroupName}/swagger.json",
                                   $"Version {apiVersionDescription.ApiVersion}");
                           }
                       });
            app.UseCustomizedMvc();
            app.UseCustomizedStaticFiles(env);
            app.ApplicationServices.GetService<ITcpService>().Start(int.Parse(Configuration["SystemSettings:TcpListenPort"]));
        }
    }
}
